#include "../aux.h"

int account_number;
char* pin;
int fd;
int fd_ans;
int pid;


/**
 * Prints the menu with the options for a common user
 */
void ShowMenu(){
	
	system("clear");
	printf("\n"	"***************************************\n"
				"**    ATM MACHINE - XPTO EDITION     **\n"
				"***************************************\n\n\n");
	
	printf("Choose an operation:\n");
	printf(" 1- Withdraw\n");
	printf(" 2- Deposit\n");
	printf(" 3- Transfer\n");
	printf(" 4- Consult\n");
	printf(" 5- Exit\n\n");
	
}


/**
 * This function writes in the logfile
 */
void writelogfile(char* op){
	FILE *logfile;
	logfile = fopen("logfile.txt", "a+");
	char actualtime[70];
	char *task=(char*)malloc(256);
	int ch;
	time_t temp;
	struct tm *timeptr;
	temp = time(NULL);
	timeptr = localtime(&temp);
	ch = strftime(actualtime, sizeof(actualtime)-1, "\n20%y-%m-%d %OH:%OM:%OS \0", timeptr);
	sprintf(task, "CLIENT     ");
	strcat(task, op);
	fwrite(actualtime,1, ch, logfile);
	fwrite(task, 1, strlen(task), logfile);
	free(task);
	fclose(logfile);
}

void openFifo()
{
	fd=open("requests",O_RDWR);
	if (fd == -1) {
		printf("Server unavailable.\n");
		exit(1);
	}
}

void endfifo(){
	close(fd_ans);
	char *strfifo;
	char *i= "ans";
	strfifo = (char *) malloc(256*sizeof(char));
	sprintf(strfifo,"%s%d",i, getpid());
	unlink(strfifo);
}

void makefifo(){

   char *str;
   char *i= "ans";

   str = (char *) malloc(256*sizeof(char));

   sprintf(str,"%s%d",i, getpid());

   mkfifo(str, 0660);

   fd_ans = open(str,O_RDWR, S_IRWXU);
}

void sendRequest(Request* req)
{
	write(fd, req, sizeof(Request));
}

void ReceiveFromServer(int n)
{
	int end=1;
	while(end==1)
	{
		char *str = malloc(sizeof(char)*255);
		readline(fd_ans,str);
		switch(n)
		{
			case 1:
				end=0;
				write(STDOUT_FILENO, str, strlen(str));
				break;
			case 2:
				end=0;
				write(STDOUT_FILENO, str, strlen(str));
				break;
			case 3:
				end=0;
				write(STDOUT_FILENO, str, strlen(str));
				break;
			case 4:
				end=0;
				write(STDOUT_FILENO, str, strlen(str));
				break;
		}
	}
}


// User Operations / Requests

/**
 * Handles user login	
 * @return success
 */
int UserLogin(){
	

	system("clear");
	printf("\n"	"***************************************\n"
				"**    Welcome to the ATM Machine     **\n"
				"**           Please login            **\n"
				"***************************************\n\n\n");
	printf("Account number: ");
	scanf("%7d", &account_number);
	printf("\n PIN: ");
	scanf("%4d", &pin);
	
	return 1;
}

/**
 * Handles a money withdraw from the logged user
 */
void UserWithdraw(){
	int ammount;
	Request *req = malloc(sizeof(Request));
	printf("Ammount to withdraw: ");
	scanf("%d", &ammount);

	req->type='w';
	req->pid=pid;
	req->value=ammount;
	req->AccountNumber=account_number;
	memcpy(req->pin, pin,5);

	openFifo();

	sendRequest(req);
	ReceiveFromServer(1);
	endfifo();
}

/**
 * Handles a money deposit from the logged user
 */
void UserDeposit(){
	int deposit;
	Request *req = malloc(sizeof(Request));
	printf("Ammount to deposit: ");
	scanf("%d", &deposit);

	req->type='d';
	req->pid=pid;
	req->value=deposit;
	req->AccountNumber=account_number;
	memcpy(req->pin, pin,5);

	openFifo();

	sendRequest(req);
	ReceiveFromServer(2);
	endfifo();
}

/**
 * Handles a money transfer from the logged user
 */
void UserTransfer(){
	int target;
	int ammount;
	Request *req = malloc(sizeof(Request));
	printf("Number of the target account: ");
	scanf("%d", &target);
	printf("Ammount to transfer: ");
	scanf("%d", &ammount);

	req->type='t';
	req->pid=pid;
	req->value=ammount;
	req->AccountNumber=account_number;
	req->TargetAccount=target;
	memcpy(req->pin, pin,5);

	openFifo();

	sendRequest(req);
	ReceiveFromServer(3);
	endfifo();

}

/**
 * Shows the logged user account details, like the balance of the account
 */
void UserConsult(){

	Request* req =  malloc(sizeof(Request));

	req->type = 'c';
	req->AccountNumber = account_number;
	req->pid=pid;
	memcpy(req->pin, pin,5);

	openFifo();

	sendRequest(req);
	ReceiveFromServer(4);
	endfifo();
}

/**
 * The main function
 */
int main(){

	pid=getpid();

	if (UserLogin()){
	
	makefifo();
	ShowMenu();
	int option;

	while (option != 5) {
		
		printf("Operation: ");
		scanf("%d", &option);
		CleanStdin();
	
			switch (option) {
		
				case 1:		//Withdraw
				UserWithdraw();
				break;

				case 2:		//Deposit
				UserDeposit();
				break;

				case 3:		//Transfer
				UserTransfer();
				break;

				case 4:		//Consult
				UserConsult();
				break;
				
				case 5:		//Exit
				printf("The program will now exit.\n");
				break;				

				default:
				printf("Your input is invalid. Please, try again.\n");
				break;
			}
			
		}
	}
	
	return 0;
}


